#pragma once
#include <QString>
#include <QIcon>

#include "util.h"
#include "base.qpb.h"
#include "gateway.qpb.h"
#include "friend.qpb.h"
#include "file.qpb.h"
#include "speech.qpb.h"
#include "transmit.qpb.h"
#include "message.qpb.h"
#include "user.qpb.h"
#include "notify.qpb.h"

namespace model
{
    /////////////////////////////////////////////////
    // 用户信息
    /////////////////////////////////////////////////
    class UserInfo
    {
    public:
        QString _user_id = "";    // 用户id
        QString _nickname = "";   // 用户昵称
        QString _desciption = ""; // 用户签名
        QString _mail = "";       // 用户邮箱
        QIcon _avatar;            // 用户头像

        // 从protobuf的userInfo对象转换为当前的userInfo对象
        void load(const LYZ::UserInfo &userInfo)
        {
            this->_user_id = userInfo.userId();
            this->_nickname = userInfo.nickname();
            this->_desciption = userInfo.description();
            this->_mail = userInfo.mail();
            if (userInfo.avatar().isEmpty())
                this->_avatar = QIcon(":/resource/image/defaultAvatar.png");
            else
                this->_avatar = makeIcon(userInfo.avatar());
        }
    };

    /////////////////////////////////////////////////
    // 消息信息
    /////////////////////////////////////////////////
    enum MessageType
    {
        STRING_TYPE,  // 文本
        IMAGE_TYPE,   // 图片
        FILE_TYPE,    // 文件
        SPEECH_TYPE   // 语音
    };

    class MessageInfo
    {
    public:
        QString _message_id = "";                   // 消息id
        QString _chat_session_id = "";              // 消息所属会话
        QString _time = "";                         // 消息发送时间
        MessageType _message_type = STRING_TYPE;    // 消息类型
        UserInfo _sender;                           // 消息发送方
        QByteArray _content;                        // 消息正文
        QString _file_id = "";                      // 文本消息该字段无效
        QString _file_name = "";                    // 仅文件消息有效

        // extra_info: 对与文件消息时作为文件名
        static MessageInfo makeMessage(MessageType message_type,
                                       const QString &chat_session_id,
                                       const UserInfo &sender,
                                       const QByteArray &content,
                                       const QString &extra_info = "")
        {
            if (message_type == STRING_TYPE)
                return makeStringMessage(chat_session_id, sender, content);
            else if (message_type == IMAGE_TYPE)
                return makeImageMessage(chat_session_id, sender, content);
            else if (message_type == FILE_TYPE)
                return makeFileMessage(chat_session_id, sender, content, extra_info);
            else if (message_type == SPEECH_TYPE)
                return makeSpeechMessage(chat_session_id, sender, content);
            else
                return MessageInfo();
        }

        bool load(const LYZ::MessageInfo &msgInfo)
        {
            this->_message_id = msgInfo.messageId();
            this->_chat_session_id = msgInfo.chatSessionId();
            this->_time = formatTime(msgInfo.timestamp());
            this->_sender.load(msgInfo.sender());
            auto type = msgInfo.message().messageType();
            if (type == LYZ::MessageTypeGadget::MessageType::STRING)
            {
                this->_message_type = STRING_TYPE;
                this->_content = msgInfo.message().stringMessage().content().toUtf8();
            }
            else if (type == LYZ::MessageTypeGadget::MessageType::IMAGE)
            {
                this->_message_type = IMAGE_TYPE;
                if (msgInfo.message().imageMessage().hasImageContent())
                    this->_content = msgInfo.message().imageMessage().imageContent();
                if (msgInfo.message().imageMessage().hasFileId())
                    this->_file_id = msgInfo.message().imageMessage().fileId();
            }
            else if (type == LYZ::MessageTypeGadget::MessageType::FILE)
            {
                this->_message_type = FILE_TYPE;
                if (msgInfo.message().fileMessage().hasFileContents())
                    this->_content = msgInfo.message().fileMessage().fileContents();
                if (msgInfo.message().fileMessage().hasFileId())
                    this->_file_id = msgInfo.message().fileMessage().fileId();
                if (msgInfo.message().fileMessage().hasFileName())
                    this->_file_name = msgInfo.message().fileMessage().fileName();

            }
            else if (type == LYZ::MessageTypeGadget::MessageType::SPEECH)
            {
                this->_message_type = SPEECH_TYPE;
                if (msgInfo.message().speechMessage().hasFileContents())
                    this->_content = msgInfo.message().speechMessage().fileContents();
                if (msgInfo.message().speechMessage().hasFileId())
                    this->_file_id = msgInfo.message().speechMessage().fileId();
            }
            else
            {
                ERROR() << "消息类型错误";
                return false;
            }
            return true;
        }


    private:
        static MessageInfo makeStringMessage(const QString &chat_session_id, const UserInfo &sender, const QByteArray &content)
        {
            MessageInfo msg;
            msg._message_type = STRING_TYPE;
            msg._message_id = makeId("M");
            msg._chat_session_id = chat_session_id;
            msg._time = formatTime(getTime());
            msg._sender = sender;
            msg._content = content;
            return msg;
        }
        static MessageInfo makeImageMessage(const QString &chat_session_id, const UserInfo &sender, const QByteArray &content)
        {
            MessageInfo msg;
            msg._message_type = IMAGE_TYPE;
            msg._message_id = makeId("M");
            msg._chat_session_id = chat_session_id;
            msg._sender = sender;
            msg._content = content;
            return msg;
        }
        static MessageInfo makeFileMessage(const QString &chat_session_id, const UserInfo &sender, const QByteArray &content, const QString &file_name)
        {
            MessageInfo msg;
            msg._message_type = FILE_TYPE;
            msg._message_id = makeId("M");
            msg._chat_session_id = chat_session_id;
            msg._time = formatTime(getTime());
            msg._sender = sender;
            msg._content = content;
            msg._file_name = file_name;
            return msg;

        }
        static MessageInfo makeSpeechMessage(const QString &chat_session_id, const UserInfo &sender, const QByteArray &content)
        {
            MessageInfo msg;
            msg._message_type = SPEECH_TYPE;
            msg._message_id = makeId("M");
            msg._chat_session_id = chat_session_id;
            msg._time = formatTime(getTime());
            msg._sender = sender;
            msg._content = content;
            return msg;

        }
    };

    /////////////////////////////////////////////////
    // 会话信息
    /////////////////////////////////////////////////
    class ChatSessionInfo
    {
    public:
        QString _chat_session_id = "";      // 聊天会话id
        QString _chat_session_name = "";    // 聊天会话名, 单聊为对方名称
        MessageInfo _last_message ;         // 最新消息
        QIcon _avatar;                      // 聊天会话头像, 单聊为对方头像
        QString _user_id = "";              // 如果是单聊会话, 表示为对方id; 如果是群聊设置为空

        bool load(const LYZ::ChatSessionInfo &chatSessionInfo)
        {
            this->_chat_session_id = chatSessionInfo.chatSessionId();
            this->_chat_session_name = chatSessionInfo.chatSessionName();
            if (chatSessionInfo.hasSingleChatFriendId())
                this->_user_id = chatSessionInfo.singleChatFriendId();
            if (chatSessionInfo.hasPrevMessage())
            {
                if (!this->_last_message.load(chatSessionInfo.prevMessage()))
                    return false;
            }
            if (chatSessionInfo.hasAvatar() && !chatSessionInfo.avatar().isEmpty())
            {
                this->_avatar = makeIcon(chatSessionInfo.avatar());
            }
            else
            {
                if (_user_id != "")
                    this->_avatar = QIcon(":/resource/image/defaultAvatar.png");
                else
                    this->_avatar = QIcon(":/resource/image/groupAvatar.png");
            }
            return true;
        }
    };

}  // end model
